Weerstation

Weer, regen en zonnecel opbrengst informatie station (v17 May 2020)

Inhoud

Weer-station project

Bij mij huidige weerstation begaf de buitensensor het. Deze gaf de buiten temperatuur en vochtigheid door aan de basis unit. In eerste instantie was ik aan het zoeken naar een nieuw weerstation maar las op het internet verschillende artikelen over arduino projecten en wat je daar allemaal mee kon. Dit wilde ik ook wel eens proberen. Bovendien is een weerstation met buitensensoren eigenlijk ouderwets, alle informatie is toch op internet te vinden redeneerde ik. Daarom besloten om zelf een weerstation te bouwen. Dit station moet de weer-informatie halen van het internet voor mijn lokale situatie en laten zien op een display. Na de nodige uren knutselen is dit het resultaat:

Weer-station aan de muur

Het station hestaat uit de volgende delen:

Weather-station functional parts

Het informatie display heeft 3 regels. Bovenste geeft de locatie (beetje overbodig misschien). De middelste geeft de wind richting en sterkte. De derde regel wisselt tussen verschillende andere soorten informatie, zie hieronder.

0> Weer display function mode 0 >1 Weer display function mode 1 >2 Weer display function mode 2 >3 Weer display function mode 3 >4 Weer display function mode 4 >5 Weer display function mode 5 >6 Weer display function mode 6 >7 Weer display function mode 7 >8 Weer display function mode 8
  1. De datum en tijd wanneer de informatie voor het laatst is opgehaald van het internet.
  2. De minimum en maximum temperatuur van de dag.
  3. De luchtdruk in mBar. Gevolgd door een trend teken. Een enkele min betekent dat de luchtdruk is gezakt, een plus dat deze is gestegen in het laatste uur. Meer minnen en plussen geeft een sterkere daling of stijging aan.
  4. De voorspelde kans dat er regen valt op deze dag.
  5. De voorspelde kans op zonneschijn op deze dag.
  6. De zons opkomst en ondergangs tijden.
  7. De lucht zichtbaarheid.
  8. Weer alarm voor de regio. Groen betekent geen alarm. Alarm kent 3 fases, geel, oranje en rood. (dit wordt ook weergegeven door de RGB LED).
  9. Een steekworden omschrijven van het weerbeeld, bv "zwaar bewolkt".

Verder zijn er 2 drukknoppen. De zwarte wisselt de mode van het onderste display tussen temperatuur, regen en zonnepanelen opbrengst. De blauwe knop wordt gebruikt om het weerstation opnieuw op te starten. Dit is helaas soms nodig. Af en toe loopt de software vast en doet het station niets meer.

De voeding is een eenvoudige USB voeding. De ESP8266 controller heeft een mini USB connector aansluiting.

Het onderste display heeft uiteindelijk 3 modes gekregen. Dit om temperatuur, regen of zonnepanelen opbrengst te kunnen laten zien:

Temperature info <-> Raininfo <-> Solarinfo

In de temperatuur mode wordt in het midden in groot font de huidige temperatuur getoond. In de links onder en rechts onder hoeken staat de voorspelde respectivelijk minimale en maximale temperatuur voor die dag. In het midden onder is de huidige gevoels temperatuur. Al deze informatie komt van een weer server. In de regen mode laat het display een staafdiagram zien met tijdsintervallen van 5 min. Het display kan hiermee zo'n 2 uur vooruit de voorspelling laten zien. De regen informatie komt van een regen server. De waarde die de regen server doorgeeft voor elk 5 min interval ligt tussen 0 and 255. De schaal is niet lineair maar logaritmisch. Om zinnige waarden te tonen vertaal ik de ontvangen waarde van de server naar één die beter op het display past. (zie deze site en de sketch 3_loop beneden voor meer info. De 3 horizontale lijnen geven resp 0.1, 1 and 10 mm/uur neerslag. Tot slot, in zonneopbrengst mode geeft het display weer een staafdiagram. Dit keer per uur de opbrengst in KWH. De horizontale lijnen zijn resp 0.5, 1.0, 1.5 en 2.0 KWH. Het max wat mijn installatie kan opwekken ligt rond de 2.5 KWH. In de bovenhoek wordt de totale opbrengst van de dag (tot nu toe) en van het laatste uur weergegeven.

De hardware

Na wat onderzoek besloten om te gaan voor een NodeMCU ESP8266 controller met ingebouwde WiFi. Deze is klein en te programeren met de standaard Arduino software. Ook de keuze gemaakt voor permanent 2 displays, één om steeds de actuele buiten temperatuur op te laten zien en één voor verschillende andere weer info zaken. Gedurende het project ontdekte ik ook dat er een server is op het internet waar de regenvoorspelling voor de komende uren te downloaden is. En ook mijn zonnepanelen opbrengst bleek op de site van de omvormer leverancier (SolarEdge) te downloaden. Daarom besloten om voor het temperatuurs display 3 modes te maken waarop dus of de temperatuur, of de regenvoorspelling of de opbrengst van de zonnepanelen op te zien is.

Geekcreit ESP8266E controller Geekcreit OLED 64x128 display RGB LED with common cathode

De NodeMCU ESP6288 is breed verkrijgbaar op het internet en bovendien goedkoop (ca €15). Ik bestelde er 2. Bleek dat de ene rev E was en de andere rev F. Ik heb geen verschillen kunnen ontdekken in deze 2 versies. Ze werkte allebei met dezelfde software. Het OLED display is 1 inch (diagonaal 25mm) groot en heeft een resolutie van 64 vertikaal bij 128 horizontaal. Deze displays werken met een zogenaamde SDD1306 chip en het I2C protocol voor communicatie met de ESP8266. Dit protocol heeft slechts 2 draden nodig met de controller (buiten nog 2 voedings aansluitingen). Dus totaal maar 4 pinnen. Kwam er wel achter dat niet alle fabrikanten even consequent zijn met de volgorde van de pinnen. De voeding (VSS), GND (VDD), SCL en SDA pins zitten dus niet altijd in dezelfde volgorde. Let hier op als je deze aansluit.

Hoe het allemaal met elkaar verbonden is.

Allereerst heb ik alles opgebouwd op een zogenaamd breadboard en met elkaar verbonden. Daarna schema vastgelegd met Fritzing. Dit is free-ware software dat ideaal lijkt voor dit soort toepassingen. Fritzing heeft bibliotheken met alle onderdelen in huis, ook de OLDE en ESP8266. Met Fritzing kun je zowel een breadboard opstelling maken alsook een schema hoe alles verbonden is. Deze zijn aan elkaar gekoppeld in Fritzing zodat je tussen deze naadloos heen en weer kunt schakelen.

Fritzing breadboard setup

Zoals je kunt zien zijn de displays en drukknoppen rechtstreeks verbonden met de ESP8266 controller. De situatie rond de RGB LED is wat complexer. Dit komt omdat de RGB LED meer dan 3v3 nodig heeft om te kunnen werken. De USB voeding geeft 5v aan de controller maar intern wordt dit omgeet naar 3.3 . Daarom wordt de RGB LED vanuit de 5v gevoed. Een uitgang laag zorgt dat de aangesloten LED aan gaat. De dioden zijn nodig om een en ander onafhankelijk van elkaar te laten werken. Dmv het schema is de werking rond de RGB LED eenvoudiger te begrijpen:

Fritzing schematics

De B van de RGB wordt niet gebruikt, alleen de Groene en Rode zijn aangesloten. Door alleen de Rode LED aan te sturen kijg je een rode kleur. Door Rood en Groen te combinenen kun je geel en oranje maken. Met 50% groen en 100% rood krijg je oranje. Met 100% groen en 100% rood krijg je geel. Het verschil is wel wat subtiel en niet altijd even duidelijk. Daarom is de alarm code kleur ook als tekst tegevoegd aan het info display.

De internet servers

De sketch (zo heet dat in deArduino wereld) software gebruikt 4 verschillende internet servers voor alle soorten informatie.

Weer informatie

De weer server geeft informatie over de temperatuur, wind sterkte en richting etc. Dit is een nederlandse server. In je browser kun je de response van de server controleren door het volgende URL adres in te voeren:

Browser URL = weerlive.nl/api/json-data-10min.php?key=PRIVATE_APIKEY&locatie=PRIVATE_CITY

The PRIVATE_APIKEY and PRIVATE_CITY you have to fill in yourself. The weather server sends back a response in JSON (Java Script Object Notation) format like this:

{ "liveweer": [{"plaats": "PRIVATE_CITY", "temp": "13.8", "gtemp": "13.8", "samenv": "Lichte regen", "lv": "79", "windr": "NNW", "windms": "1", "winds": "1", "windk": "1.9", "windkmh": "3.6", "luchtd": "1015.9", "ldmmhg": "762", "dauwp": "9", "zicht": "16", "verw": "Vooral in een strook van west naar oost regen, in het noorden droog en zon", "sup": "06:30", "sunder": "20:42", "image": "buien", "d0weer": "halfbewolkt", "d0tmax": "23", "d0tmin": "8", "d0windk": "3", "d0windknp": "8", "d0windms": "4", "d0windkmh": "15", "d0windr": "N", "d0neerslag": "4", "d0zon": "62", "d1weer": "zonnig", "d1tmax": "18", "d1tmin": "6", "d1windk": "3", "d1windknp": "8", "d1windms": "4", "d1windkmh": "15", "d1windr": "NO", "d1neerslag": "10", "d1zon": "80", "d2weer": "zonnig", "d2tmax": "18", "d2tmin": "7", "d2windk": "3", "d2windknp": "8", "d2windms": "4", "d2windkmh": "15", "d2windr": "O", "d2neerslag": "10", "d2zon": "80", "alarm": "0"}]}

De weerinformatie is in het zogenaamde JSON (Java Script Object Notation) format gegroepeerd bij naam en waarde. B.v. "temp": "13.8" betekent actuele temperatuur is 13.8 graden. De betekenis van alle namen is uitgelegd in de code van 3_loop sketch. Niet alle informatie die de weerserver terugstuurd wordt daadwerkelijk gebruikt in dit project. De APIKEY moet door de gebruiker worden aangevraagd op de website van de server, zie hieronder.

Regen informatie

De server gebruikt GPS coordinaten for the locatie. Dit werkt misschien alleen rond nderderland. Ik heb dit niet geprobeerd. De komplete URL voor de browser is dan:
Browser URL = gpsgadget.buienradar.nl/data/raintext?PRIVATE_COORDINATES

Browser URL = gpsgadget.buienradar.nl/data/raintext?lat=xx.x1&lon=x.xx

De server reageert door onderstaande data terug te sturen. Grofweg is dit de regenvoorspelling voor de komende 2 uur:

000|17:25
000|17:30
010|17:35
032|17:40
056|17:45
011|17:50
005|17:55
000|18:00
000|18:05
000|18:10
000|18:15
000|18:20
000|18:25
000|18:30
000|18:35
054|18:40
145|18:45
070|18:50
000|18:55
000|19:00
000|19:05
000|19:10
000|19:15

Regen en tijd informatie gescheiden door een | symbool. De server stuurt ook een header, die is niet relevant voor de browser en daarom laat de browser die niet zien. De sketch software ziet die wel en moet deze verwerken.

Zonnepanelen opbrengst

De Solaredge server geeft de gegenereerde energie van de panelen op ons dak voor de gevraagde dag. De server kan veel meer informatie sturen maar ik beperk me tot deze gegevens.

Browser URL = monitoringapi.solaredge.com/site/PRIVATE_SOLAR_SITE/energy?timeUnit=HOUR&endDate=2020-05-16&startDate=2020-05-16&api_key=PRIVATE_SOLAR_APIKEY

De server reactie is in JSON formaat en ziet er als volgt uit:

{"energy":{"timeUnit":"HOUR","unit":"Wh","measuredBy":"INVERTER","values":[{"date":"2020-05-14 00:00:00","value":null},,{"date":"2020-05-14 12:00:00","value":2010.132},,{"date":"2020-05-14 23:00:00","value":null}]}}

De regel is nogal lang en daarom heb ik de tussenliggende uren er maar even uitgelaten. De waarde is de opbrengst in dat uur. Dus de 2010.132 wh is opgewekt tussen 12:00 en 13:00.

Datum en tijd

De ESP controller heeft wel een RTC (Real Time Clock) aan boord maar deze moet wel geïnitialiseerd worden en loopt niet exact gelijk. Om de juiste datum en tijd voor mijn lokale situatie weer te geven wilde ik gebruik maken van een internet server. De datum wordt gebruikt in de URL van de SolarEdge server. De tijd wordt ook gebruikt om energie opbrengst weer te geven van het huidige uur. Tot slot wordt datum en tijd van de laatste keer dat informatie was opgehaald van de internet servers ook in het display weergegeven.

De weer, regen en zonneopbrengst servers geven in hun bericht die ze terugsturen ook de datum en tijd informatie mee. Dit is echter in een bepaald formaat en in GMT (Greenwich Middle Time) tijd. Hieronder een paar regels van een typische reactie van de internet servers:

HTTP/1.1 200 OK
Date: Sun, 17 May 2020 10:49:03 GMT
Server: Apache/2.4.41 (Unix)
X-Powered-By: PHP/7.3.16
Content-Type: text/html
Connection: close
Transfer-Encoding: chunked

De maand is in tekst, ik heb een nummer nodig. De time zone is GMT. Om dat om te zetten naar lokale tijd moet ik dit vertalen. Dit is lastig. Omddat ik toch al informatie ophaal van verschillende server heb ik besloten om de datum en tijd informatie van mijn eigen website te halen. Hiervoor maak ik gebruik van de software van de hosting provider. Deze werkt voor mij als een timeserver. Om dit te bewerkstelligen heb ik een klein PHP programmaatje gemaakt dat aleen de datum en tijd terurstuurd. De datum is meteen in het format dat de ESP controller nodig heeft en de tijd is meteen gecorrigeerd voor zomer/winter tijd. Dit is het PHP programmatje:

<?php
// timeserver
$currentDate = date("Y-m-d"); // e.g. 2020-05-16
$localTime = date("H:i"); // e.g. 08:34
echo <<<_END
yyyy-mm-dd=$currentDate<br />
hh:mm=$localTime<br />
_END;
?>

Dit opgeslagen op de website als een timestamp.php bestand. Door dit bestand aan te roepen in de browser, stuurt de hosting server de volgende reactie:

yyyy-mm-dd=2020-05-17
hh:mm=12:59

Doordat de browser een en ander uitfiltert cq vertaald is de eigenlijke data die de controller ontvangt:

yyyy-mm-dd=2020-05-17<br />
hh:mm=12:59<br />

Dus inclusief de einde regel karakters. Het is dan nog een fluitje van een cent om uit deze data de benodigde datum en tijd te halen.

De software

Gebruik gemaakt van de gratie beschikbare Arduino IDE v1.8.12 voor de software. Er is een enorme hoeveelheid boeken en voorbeeld programma's op het internet te vinden. Dit was een belangrijke bron voor me omdat ik nog niet eerder een Arduino project had gedaan.

Arduino IDE board selection

Zorg er voor dat je het juiste bord/controller selecteerd in Arduino. Voor het weerstation was dit dus de "NodeMCU 1.0 ESP-12E". De maker van de controller die ik heb gekocht was Geekcreit, deze is compatibel met de NodeMCU. Zorg er voor dat je versie 1.0 van de NodeMCU selecteert en niet per ongeluk de 0.9. Deze laatste is een heel andere controller. Zorg ook dat je de beschikbare standaard software voor de ESP8266 download (via de board manager: Tools -> Board: NodeMCU 1.0 (ESP-12E module) -> Board manager). Voor mijn project heb ik versie 2.6.1. van de bibliotheek gebruikt.

Tijdens het maken van de software merkte ik dat het handig is de sketch op te delen in kleinere stukjes. Als de Arduino IDE verschillende *.ino bestanden vind in dezelfde folder dan laat de software deze zien in elk hun eigen tab. Hierdoor kun je wat makkelijker switches tussen de verschillende software stukken en hoef je minder te scrollen. The Arduino software verwerkt de deel sketches in een specifieke volgorde namelijk: eerst de hoofdsketch en daarna in alphabetische volgorde de andere sketches. In principe dus de tabs van links naar rechts. In het screenshot hieronder kun je zien dat ik uiteindelijk 6 sketches heb die gezamelijk aan elkaar geknoopt het programma vormen:

Arduino sketches split

De Arduino IDE laadt ook alle .h en .cpp bestanden die in dezelfde folder staan. Dit zijn standaard bibliotheken die door mij zijn aangepast voor dit project.

Sketch: ron-weerstationv18

Deze sketch is erg klein. Het beschrijft het project en laadt 2 bibliotheken die nodig zijn voor mijn project.

De ESP8266WiFi bibliotheek bevat weer meerdere bibliotheken die nodig zijn om de controller te verbinden met de WiFi en om verbinding te maken met de internet servers.

Verder definieert deze sketch of debug mode aan of uit staat. In debug mode worden bepaalde regels geschreven naar de seriele uitgang die met de Arduino bekeken kunnen worden.

// debugging macros
//#define DEBUG				// Remove comment for DEBUG mode!
#ifdef DEBUG
	#define DPRINT(...)		Serial.print(__VA_ARGS__)     
	#define DPRINTLN(...)	Serial.println(__VA_ARGS__)   
#else
	#define DPRINT(...)		//now defines a blank line i.e. no print output
	#define DPRINTLN(...)	//now defines a blank line i.e. no print output
#endif

Met deze constructie kun door het weglaten van de // bij de define DEBUG regel de mode activeren.

Sketch: 0_private


// define private constants
const char* PRIVATE_WIFI_SSID = "";
const char* PRIVATE_WIFI_PASSWORD = "";
const char* PRIVATE_WEATHER_APIKEY = "";
const char* PRIVATE_CITY = "";
const char* PRIVATE_COORDINATES = "lat=xx.x1&lon=x.xx"; // GPS coordinates of your locations
const char* PRIVATE_SOLAR_APIKEY = "";;
const char* PRIVATE_SOLAR_SITE = "your solar site id";
const char* PRIVATE_URLT = "your time page";

In deze sketch staan prive gegevens. In de download zit een bestandje met bovenstaande regels and niet die van mijn sketch.

De SolarEdge en weer server zullen alleen de juiste data sturen als er van te voren een zg APIKEY is aangevraagd en aanwezig in de URL. Deze moet éénmalig worden aangevraagd op de site. Deze vervangt dus de tekst PRIVATE_APIKEY. De servers staan 300 verzoeken per dag toe. Dat is genoeg om elke 5 min de data op te vragen.

Sketch: 1_definition

Hier worden de constanten, variabelen en ojecten gedefinieerd die verder in het programma gebruikt worden. De meeste verklaren zichzelf. Ik haal er een paar uit om toe te lichten:

// Initialize the OLED display using Wire library
SSD1306Wire  displayInfo(0x3c, D3, D4); // SDA=D3 SCL=D5, INFO display for weather info
SSD1306Wire  displayTemp(0x3c, D1, D2); // SDA=D1 SCL=D2, TEMP/RAIN display

De SDD1306Wire library wordt gebruikt voor de OLED displays. Er worden 2 objecten hier gedefinieerd omdat deze onafhankelijk van elkaar gebruikt moeten worden.

WiFiClient clientH;			// to connect to an insecure (HTTP) internet server
const int httpPort = 80;

WiFiClientSecure clientS;	// to connect to a secure (HTTPS) internet server
const int httpsPort = 443;

Zo worden er ook 2 TCP clients aangemaakt, één voor een server met zg onbeveiligde verbinding (URL die begint met HTTP:) en één voor een server met een beveiligde verbinding (URL die begint met HTTPS:). Deze gebruiken allebei een ander poort nr. Poort 80 is de standaard voor HTTP, 443 is de standaard voor HTTPS. De software maakt verbinding met 4 verschillende servers. De tijd, regen en zonne server maken allemaal gebruik van de clientS en poort 443. De clientS kan gebruikt worden voor meerdere servers omdat steeds eerst de data wordt opgehaald en verwerkt voor verbinding wordt gemaakt met de volgende clientS server. Daarom is 1 instantie van clientS voldoende. De weer server gebruikt clientH en poort 80.

// enumeration for modes button
enum DISPLAY_MODE {DISPLAY_MODE_WEATHER = 0,DISPLAY_MODE_RAIN = 1,DISPLAY_MODE_SOLAR = 2};

Om de code wat leesbaarder te maken heb ik voor de 3 temp display modi een zogenaamde 'enumeration' variabele gemaakt. Hiermee kun je code schrijven zoals DisplayMode = DISPLAY_MODE_RAIN.

// define  global variables (start with uppercase letter, local variables start with lower case)
String CurrentDate = "2020-01-01";
String CurrentTime = "00:00";

De datum en tijd worden gebruikt in de zonne opbrengst URL en wordt weergegeven op het info display. De datum en tijd geven dan het moment waarop het weerstation voor de laatste keer de informatie heeft opgehaald van de server. Dit is dus nooit langer dan 5 min geleden.

Sketch: 2_setup

Hier worden de pinnen van de ESP8266 gedefinieerd voor input of output.
De seriele pooty voor debug messages wordt geinitialiseerd en ingesteld op de maximale snelheid (zogenaamde baud rate).
Beide OLED displays worden geinitialiseerd. In eerste instantie kon ik de 2 displays niet gezamelijk werked krijgen. Op internet vond ik de volgende regels die dit probleem voor me oplosten:

	// This will make sure that multiple instances of a display driver
	// running on different ports will work together transparently
	displayInfo.setI2cAutoInit(true);
	displayTemp.setI2cAutoInit(true);

Sketch: 3_loop

In deze sketch wordt het meeste werk gedaan. De sketch kan worden opgesplitst in:

De stappen die steeds gevolgd worden om verbinding te maken met een internet server en de data op te halen kun je als volgt visualiseren: Flow diagram client

Wanneer de server geen geldige reactie heeft gestuurd dan wordt 'DATA NOT FOUND' op het display afgebeeld.

Om een verbinding te maken met een onbeveiligde HTTP server zijn de volgende stappen van belang:

Wanneer een verbinding gemaakt moet worden met een beveiligde HTTPS server zijn de stappen bijna hetzelfde:

Dit vraagt enige toelichting. Hoewel er dus een verbindig wordt gemaakt met een beveiligde server wordt toch een onbeveiligde verbinding toegestaan! Dit betekent eigenlijk dat het weerstation niet 100% zeker weet of de ontvangen data daadwerkelijk van de gevraagde server komt of van een hacker. Omdat het weerstation alleen publiekelijk op te vragen gegevens ontvangt en de ontvangen data ook wordt gecheckt op correctheid is dit geen risico. Mocht het toch misgaan dan houdt het weerstation hoogstens op te functioneren. Er is geen risico op binnendringing in mijn netwerk. Om een beveiligde verbinding op te zetten tessen een gebruiker en een server is een zogenaamde vingerafdruk nodig. Door deze vingerafdruk weet de gebruiker dat hij daadwerkelijk verbinding heeft met de server. Het nadeel van ee vingerafdruk is dat deze een beperkte geldigheid heeft en hard gecodeerd moet worden in de software. Dus nadat de datum verlopen is moet je weer een nieuwe vingerafdruk in de code zetten. Dat is niet handig. Een browser doet dit allemaal naadloos voor de gegruiker achter de schermen en zal automatisch ook de vingerafdruk verversen als dat nodig is. Een vingerafdruk zou er ongeveer als volgt uit zien in de code:

const uint8_t fingerprint[20] = {0x5A, 0xCF, 0xFE, 0xF0, 0xF1, 0xA6, 0xF4, 0x5F, 0xD2, 0x11, 0x11, 0xC6, 0x1D, 0x2F, 0x0E, 0xBC, 0x39, 0x8D, 0x50, 0xE0};

Om deze te gebruiken vervang je de regel met clientS.setInsecure(); door een regel met clientS.setFingerprint(fingerprint);

Om een vingerafdruk te verkrijgen kun je de Chrome of Edge browser gebruiken. Ga naar de website en druk op F12 of Ctrl-Shift-i om de pagina te inspecteren. Kies dan voor de 'beveiligings tabblad' en kies vervolgens 'bekijk certificaat':

Chrome inspection screen

In het window dat opent kun je de verval datum zien en op de detail tabblad ook de vingerafdruk zelf. Deze moet je dan in de sketch opnemen: Ik heb dat zelf niet geprobeerd.

Certificate pop-up window general tab Certificate pop-up window details tab

Font

Voor de tijdelijke aflezing in het TEMP-display wilde ik een groot pixellettertype dat precies op het display zou passen en van een afstand kon worden gelezen. De standaardbibliotheek had niet zo'n groot lettertype. Op internet vond ik op oleddisplay.squix.com een site waar je je eigen lettertype kunt maken. Vervolgens heb ik de gegenereerde code gekopieerd naar het OLEDDisplayFonts.h-bestand. Omdat ik het lettertype heb aangepast, heb ik het OLEDDisplayFonts.h-bestand in de schetsmap geplaatst. Dit zorgt ervoor dat de gewijzigde bibliotheek wordt gebruikt in plaats van de standaardbibliotheek. Binnen de code kunt u dit lettertype selecteren met de regel:

	displayTemp.setFont(Lato_Regular_52);

Bibliotheken

Een bibliotheek is een verzameling tools / functies / code voor een specifiek doel. Deze zijn erg handig en besparen veel diepe duikontwikkeling en uren. Een enkele bibliotheek bestaat (meestal) uit 2 bestanden. Een zogenaamd header-bestand met de definities en met de extensie ".h" en de programmacode voor de bibliotheek met extensie ".cpp". Zoals hierboven vermeld, kan een bibliotheek worden gebruikt in een schets met het commando #include "library ". Merk op dat de OLEDDisplayFonts-bibliotheek alleen een headerbestand heeft. Deze bibliotheek heeft alleen een definitie en geen daadwerkelijke code. Een bibliotheek kan zelf ook andere bibliotheken bevatten. Dit is meestal het geval. Het is dus niet altijd duidelijk welke bibliotheken bij een schets betrokken zijn. Dit is meestal ook niet zo'n probleem. Daar zorgt de Arduino IDE voor.

Bibliotheken kunnen op verschillende locaties op uw computer staan:

  1. In de schetsmap
    Hier heb ik mijn gewijzigde bibliotheek voor het lettertype en een gedownloade bibliotheek voor de interface met de OLED-schermen opgeslagen.
    Deze map kan zich op een locatie naar keuze bevinden. Ik plaats de mijne op mijn NAS-station, maar het kan ook in de map Windows C:/Users/XXX/Documents staan.
  2. In de boardmap
    Zoals eerder vermeld, moet u uw bord selecteren in de Arduino IDE-bordmanager
    Hiermee download je ook de bibliotheken die specifiek zijn voor je forum. Op mijn computer was dit opgeslagen in C:\Users\ron\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1
  3. In de Arduino IDE-map
    Dit zijn bibliotheken voor algemeen gebruik die worden geleverd bij de installatie van de Arduino IDE
    Ik gebruik versie Arduino v1.8.12 op Windows 10. De bibliotheken zijn opgeslagen in C:\Program Files (x86)\Arduino\libraries

Ik denk dat dit ook de volgorde is waarin de Arduino IDE op zoek gaat naar een bibliotheek die moet worden opgenomen. Ik kon de OLEDDisplayFonts-bibliotheek 'overschrijven' door deze direct in de schetsmap te plaatsen. Kijk voor meer informatie over Arduino bibliotheken op www.arduino.cc.

Mijn schets bevat 2 bibliotheken, de ESP8266WiFi.h, een van de bordbibliotheken en de SDD1306Wire-bibliotheek die ik van internet heb gedownload en in de schetsmap staat. De IDE zal tijdens de compilatie veel meer bibliotheken bevatten die zijn opgenomen, maar waarschijnlijk ook bibliotheken die niet expliciet zijn opgenomen, maar deel uitmaken van de kern.

Geheugen gebruik

Ik denk dat mijn schets niet erg geheugen vriendelijk is. Ik heb veel Global String variabelen en Global String konstanten gebruikt. Dat wil zeggen String met een hoofdletter 'S'. Het String object heeft veel manipulatiefuncties, dit maakt het gemakkelijk om met strings te werken maar voegt ook wat overhead toe aan elke variabele. U kunt bijvoorbeeld de functie InputLine.indexOf ("Date:") gebruiken om te achterhalen of de tekst "Date:" aanwezig is in de String InputLine. Dit is moeilijker met de standaard char array.

Hier is een geheugenrapport van de compiler voor verschillende situaties:

De belangrijke waarden heb ik gemarkeerd in rode tekst. Zoals je kunt zien wordt er met een lege schets al veel geheugen gebruikt. De totale schets draagt ​​daaraan bij, maar de toename is niet veel. De IRAM-waarde lijkt het meest kritisch. Het lijkt ook diegene te zijn waar je op schetsniveau de minste controle over hebt. De IRAM is een 32k bytes dynamisch RAM geheugen dat wordt gebruikt om schetscode (als ik dit correct heb gegoogeld) 4 keer sneller uit te voeren dan vanaf ROM. Normaal gesproken wordt de meeste code vanaf ROM uitgevoerd. Wat hier gebeurt, wordt bepaald door de ontwikkelaars van de gebruikte bibliotheken. Dit gaat mijn programmeer mogelijkheden te boven. Daarom besloot ik in mijn schets niet te proberen het geheugengebruik te verbeteren.

PS1 in de bovenstaande tabel zijn de DATA (geïnitialiseerde globale variabelen), RODATA (= Read Only DATA, globale alleen-lezen variabelen) en BSS (niet-geïnitialiseerde globale variabelen) samen het aantal bytes in de GlobalVar-kolom. De ESP heeft 80k (dynamisch lees / schrijf SRAM) geheugen voor GlobalVar, dit wordt gebruikt om het percentage te berekenen. Dit betekent dus dat ongeveer 60% van 80k = 50k beschikbaar is tijdens het aflopen van het programma.

PS2 De IROM-waarde in de tabel is het aantal bytes dat de sketch inneemt in ROM of flash geheugen. Aangezien er voldoende flash geheugen is op de ESP8266 is dit geen beperking voor de schets. Blijkbaar kun je ook de ESP8266 draadloos programmeren (genaamd OTA = Over The Air) maar ik heb dit nog nooit geprobeerd. Ik programmeer altijd via een USB-verbinding.

Dus hoe zit het geheugen wanneer het programma wordt uitgevoerd? Dit geeft toch wel een wat ander beeld. U kunt de functie ESP.getFreeHeap() gebruiken om de hoeveelheid geheugen op te halen waarmee het actieve programma kan werken en ESP.getHeapFragmentation() om de vrije beschikbare hoeveelheid alsmede de ongebruikte gaten in het dynamisch geheugen. Voor een lege schets is het vrije aantal ongeveer 49.000 bytes. Met de volledige schets die wordt uitgevoerd, wordt dit teruggebracht tot 16.000 bytes. Dit is een meer dramatische afname. Na activering van de schets is de heapfragmentatie aanvankelijk 4%. Als code langer draait, neemt de vrije ruimte een beetje af tot ongeveer 15.000 en neemt de fragmentatie toe tot 25%. Dit lijkt te stabiliseren rond deze waarden. Ik zie niet echt een noodzaak noch mogelijkheid om dit te verbeteren, dus besloot ik het voorlopig te laten. Je kunt over dit onderwerp wat meer lezen oplearn.adafruit.com

De behuizing

Omdat ik een 3D-printer bezit, heb ik besloten om zelf een behuizing te ontwerpen en te printen. Voor het ontwerp heb ik een thermometervorm gebruikt. De afmeting van de behuizing is slechts 150mm. Dus de meeste 3D-printers zouden dit moeten kunnen printen.

weatherstation housing view from the back

De afbeelding is een screenshot van een 3D-print softwareprogramma. Het aanzicht is vanaf de achterkant.

Download

De Arduino IDE en de bordbibliotheken moet u zelf van internet downloaden.

Download het ZIP bestand met alle schetsen incl aangepaste bibliotheken. Kopieer de gedownloade map niet naar uw Arduino schetsmap met Windows, maar gebruik de Arduino IDE om de ​​ZIP in de Arduino omgeving op te nemen. De Sketch map bevat ook de weer- en regenserverreactie waarop de sketch was gebaseerd.

Download het Fritzing bestand. De Fritzing-software moet je ook zelf downloaden van de fritzing.org site.

Download het STL bestand voor 3d printing.